package com.xinchuang.service.targetSystem.Impl;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.collection.ListUtil;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.xinchuang.common.Result;
import com.xinchuang.common.ResultUtil;
import com.xinchuang.entity.targetSystem.system.SystemEmulateData;
import com.xinchuang.service.targetSystem.EmulateService;
import com.xinchuang.service.targetSystem.SystemEmulateDataService;
import com.xinchuang.util.FileElseUtil;
import com.xinchuang.util.RedisUtil;
import com.xinchuang.utils.ObjectUtil;
import com.xinchuang.utils.RedisName;
import com.xinchuang.vo.SystemsRangeVo;
import lombok.RequiredArgsConstructor;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;

import java.io.File;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Service
@RequiredArgsConstructor
public class EmulateServiceImpl implements EmulateService {

    private final SystemEmulateDataService systemEmulateDataService;

    private final RedisUtil redisUtil;

    @Override
    public Result addOrUpSystemsEmulationData(JSONObject json) {
        String id = json.getString("id");
        String sysId = json.getString("sysId");
        String targetId = json.getString("targetId");
        String name = json.getString("gjName");
        String position = json.getString("positions");
        String weaponType = json.getString("modelurl");
        String speed = json.getString("speed");
        String duration = json.getString("duration");
        String color = json.getString("lineColor");
        String lineWidth = json.getString("lineWidth");
        SystemEmulateData data = systemEmulateDataService.getById(id);
        if (ObjectUtil.isEmpty(data)) {
            data = new SystemEmulateData();
            data.setSysId(sysId);
            data.setTargetId(targetId);
            data.setName(name);
            data.setPosition(position);
            data.setWeaponType(weaponType);
            data.setSpeed(speed);
            data.setDuration(duration);
            data.setColor(color);
            data.setWidth(lineWidth);
            systemEmulateDataService.save(data);
        } else {
            data.setName(name);
            data.setPosition(position);
            data.setWeaponType(weaponType);
            data.setSpeed(speed);
            data.setDuration(duration);
            data.setColor(color);
            data.setWidth(lineWidth);
            systemEmulateDataService.updateById(data);
        }
        return ResultUtil.success();
    }

    @Override
    public Result deleteSystemsEmulationData(JSONObject json) {
        String id = json.getString("id");
        systemEmulateDataService.removeById(id);
        return ResultUtil.success("删除成功", null);
    }

    @Override
    public Result selectSystemsEmulationData(JSONObject json) {
        Map<String, Object> resultMap = new HashMap<>();
        List<Map<String, Object>> resultList = new ArrayList<>();
        Integer pageNum = json.getInteger("pageNum");
        Integer pageSize = json.getInteger("pageSize");
        String sysId = json.getString("sysId");
        String targetId = json.getString("targetId");
        String id = json.getString("id");
        if (null == pageNum && null == pageSize) {
            LambdaQueryWrapper<SystemEmulateData> wrapper = new LambdaQueryWrapper<>();
            wrapper.eq(SystemEmulateData::getSysId, sysId);
            if (StringUtils.isNotBlank(targetId)) {
                wrapper.eq(SystemEmulateData::getTargetId, targetId);
            } else {
                wrapper.isNull(SystemEmulateData::getTargetId);
            }
            List<SystemEmulateData> emulateData = systemEmulateDataService.list(wrapper);
            List<Map<String, Object>> chooseList = new ArrayList<>();
            List<Map<String, Object>> noChooseList = new ArrayList<>();
            Map<String, Object> map;
            for (SystemEmulateData data : emulateData) {
                map = new HashMap<>();
                map.put("id", data.getId());
                map.put("sysId", data.getSysId());
                map.put("targetId", data.getTargetId());
                map.put("gjName", data.getName());
                map.put("positions", data.getPosition());
                map.put("modelurl", data.getWeaponType());
                map.put("speed", data.getSpeed());
                map.put("duration", data.getDuration());
                map.put("lineColor", data.getColor());
                map.put("lineWidth", data.getWidth());
                noChooseList.add(map);
                if (null != data.getShowType() && 1 == data.getShowType()) {
                    chooseList.add(map);
                }
            }
            resultMap.put("chooseList", chooseList);
            resultMap.put("noChooseList", noChooseList);
            return ResultUtil.success(resultMap);
        } else if (null != pageNum && null != pageSize) {
            LambdaQueryWrapper<SystemEmulateData> wrapper = new LambdaQueryWrapper<>();
            wrapper.eq(SystemEmulateData::getSysId, sysId);
            if (StringUtils.isNotBlank(targetId)) {
                wrapper.eq(SystemEmulateData::getTargetId, targetId);
            } else {
                wrapper.isNull(SystemEmulateData::getTargetId);
            }
            Page<SystemEmulateData> page = systemEmulateDataService.page(new Page<>(pageNum, pageSize), wrapper);
            if (CollectionUtil.isNotEmpty(page.getRecords())) {
                Map<String, Object> map;
                for (SystemEmulateData data : page.getRecords()) {
                    map = new HashMap<>();
                    map.put("id", data.getId());
                    map.put("sysId", data.getSysId());
                    map.put("targetId", data.getTargetId());
                    map.put("gjName", data.getName());
                    map.put("positions", data.getPosition());
                    map.put("modelurl", data.getWeaponType());
                    map.put("speed", data.getSpeed());
                    map.put("duration", data.getDuration());
                    map.put("lineColor", data.getColor());
                    map.put("lineWidth", data.getWidth());
                    resultList.add(map);
                }
            }
            resultMap.put("dataList", resultList);
            resultMap.put("pageNum", page.getCurrent());
            resultMap.put("pageSize", page.getSize());
            resultMap.put("total", page.getTotal());
            resultMap.put("pages", page.getPages());
            return ResultUtil.success(resultMap);
        } else if (StringUtils.isNotBlank(id)) {
            SystemEmulateData data = systemEmulateDataService.getById(id);
            if (ObjectUtil.isNotEmpty(data)) {
                resultMap.put("id", data.getId());
                resultMap.put("sysId", data.getSysId());
                resultMap.put("targetId", data.getTargetId());
                resultMap.put("gjName", data.getName());
                resultMap.put("positions", data.getPosition());
                resultMap.put("modelurl", data.getWeaponType());
                resultMap.put("speed", data.getSpeed());
                resultMap.put("duration", data.getDuration());
                resultMap.put("lineColor", data.getColor());
                resultMap.put("lineWidth", data.getWidth());
            }
        }
        return ResultUtil.success(null);
    }

    @Override
    public Result chooseEmulation(JSONObject json) {
        String sysId = json.getString("sysId");
        String targetId = json.getString("targetId");
        JSONArray chooseList = json.getJSONArray("chooseList");
        if (CollectionUtil.isNotEmpty(chooseList)) {
            systemEmulateDataService.lambdaUpdate()
                    .set(SystemEmulateData::getShowType, 2)
                    .eq(SystemEmulateData::getSysId, sysId)
                    .eq(StringUtils.isNotBlank(targetId), SystemEmulateData::getTargetId, targetId)
                    .update();
            List<String> ids = new ArrayList<>();
            for (int i = 0; i < chooseList.size(); i++) {
                JSONObject object = chooseList.getJSONObject(i);
                ids.add(object.getString("id"));
            }
            systemEmulateDataService.lambdaUpdate()
                    .set(SystemEmulateData::getShowType, 1)
                    .in(SystemEmulateData::getId, ids)
                    .update();
        }
        return ResultUtil.success();
    }

    @Override
    public Result mapToEmulate(JSONObject json) {
        Map<String, Object> resultMap = new HashMap<>();
        resultMap.put("maxTime", 0);
        resultMap.put("dataList", ListUtil.empty());
        String sysId = json.getString("sysId");
        String targetId = json.getString("targetId");
        LambdaQueryWrapper<SystemEmulateData> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(SystemEmulateData::getSysId, sysId);
        if (StringUtils.isNotBlank(targetId)) {
            wrapper.eq(SystemEmulateData::getTargetId, targetId);
        }
        wrapper.eq(SystemEmulateData::getShowType, 1);
        List<SystemEmulateData> emulateData = systemEmulateDataService.list(wrapper);
        if (CollectionUtil.isNotEmpty(emulateData)) {
            List<Map<String, Object>> list = new ArrayList<>();
            int maxTime = 0;
            Map<String, Object> map;
            for (SystemEmulateData data : emulateData) {
                int time = FileElseUtil.getObjectToInt(data.getDuration());
                if (time > maxTime) {
                    maxTime = time;
                }
                map = new HashMap<>();
                map.put("id", data.getId());
                map.put("gjName", data.getName());
                map.put("positions", FileElseUtil.getObjectToList(data.getPosition()));
                map.put("modelurl", data.getWeaponType());
                map.put("speed", FileElseUtil.getObjectToInt(data.getSpeed()));
                map.put("duration", FileElseUtil.getObjectToInt(data.getDuration()));
                map.put("lineColor", FileElseUtil.getObjectToString(data.getColor()));
                map.put("lineWidth", FileElseUtil.getObjectToString(data.getWidth()));
                list.add(map);
            }
            resultMap.put("maxTime", maxTime);
            resultMap.put("dataList", list);
        }
        return ResultUtil.success(resultMap);
    }

    @Override
    public Result mapToEmulateExtend(JSONObject json) {
        Map<String, Object> resultMap = new HashMap<>();
        resultMap.put("timeList", ListUtil.empty());
        resultMap.put("saxTime", 0);
        resultMap.put("itemModelList", ListUtil.empty());
        String sysId = json.getString("sysId");
        List<SystemEmulateData> emulateData = systemEmulateDataService
                .lambdaQuery()
                .eq(SystemEmulateData::getSysId, sysId)
                .orderByDesc(SystemEmulateData::getTargetId)
                .list();
        if (CollectionUtil.isNotEmpty(emulateData)) {
            int saxTime = 0;
            List<Map<String, Object>> itemModelList = new ArrayList<>();
            Map<String, Object> model = null;
            List<Map<String, Object>> modelList = null;
            Map<String, Object> positionMap = null;
            String targetId = null;
            for (SystemEmulateData data : emulateData) {
                if (redisUtil.hasKey(RedisName.TARGET_BASE_DATA_ALL + "_" + data.getTargetId())) {
                    if (null == targetId) {
                        targetId = data.getTargetId();
                        model = new HashMap<>();
                        modelList = new ArrayList<>();
                        model.put("targetId", targetId);
                        model.put("targetName", redisUtil.hget(RedisName.TARGET_BASE_DATA_ALL + "_" + data.getTargetId(), "targetName").toString());
                    } else if (!targetId.equals(data.getTargetId())) {
                        model.put("positionList", modelList);
                        itemModelList.add(model);
                        model = new HashMap<>();
                        modelList = new ArrayList<>();
                        model.put("targetId", targetId);
                        model.put("targetName", redisUtil.hget(RedisName.TARGET_BASE_DATA_ALL + "_" + data.getTargetId(), "targetName").toString());
                    }
                    positionMap = new HashMap<>();
                    int time = FileElseUtil.getObjectToInt(data.getDuration());
                    if (saxTime < time) {
                        saxTime = time;
                    }
                    positionMap.put("id", data.getId());
                    positionMap.put("gjName", data.getName());
                    positionMap.put("positions", detailPosition(time, FileElseUtil.getObjectToList(data.getPosition())));
                    positionMap.put("modelurl", data.getWeaponType());
                    positionMap.put("speed", FileElseUtil.getObjectToInt(data.getSpeed()));
                    positionMap.put("duration", time);
                    positionMap.put("lineColor", data.getColor());
                    positionMap.put("lineWidth", data.getWidth());
                    modelList.add(positionMap);
                }
            }
            model.put("positionList", modelList);
            itemModelList.add(model);
            resultMap.put("timeList", ListUtil.empty());
            resultMap.put("saxTime", saxTime);
            resultMap.put("itemModelList", itemModelList);
        }
        return ResultUtil.success(resultMap);
    }

    private List<Object> detailPosition(int duration, List position) {
        if (CollectionUtil.isNotEmpty(position)) {
            List<Object> list = new ArrayList<>();
            int middle = duration / (position.size() - 1);
            List<Object> main = null;
            int time = 0;
            for (int i = 0; i < position.size(); i++) {
                main = new ArrayList<>();
                if (i == position.size() - 1) {
                    main.add(duration);
                } else {
                    main.add(time);
                }
                main.add(position.get(i));
                list.add(main);
                time += middle;
            }
            return list;
        }
        return ListUtil.empty();
    }

}
